<template>
  <div class="image-upload">
    <!-- 上传区域：仅在没有图片或多图模式下显示 -->
    <div 
      v-if="imageList.length === 0 || (multiple && imageList.length < maxCount)" 
      class="upload-area" 
      @click="handleClick"
    >
      <el-upload
        ref="uploadRef"
        :show-file-list="false"
        :before-upload="beforeUpload"
        :http-request="handleUpload"
        :accept="accept"
        :multiple="multiple"
        :disabled="disabled || uploading"
        drag
      >
        <div class="upload-content">
          <div class="upload-placeholder">
            <el-icon class="upload-icon"><Plus /></el-icon>
            <div class="upload-text">点击或拖拽上传图片</div>
            <div class="upload-tip">支持 JPG、PNG、GIF、WebP 格式，大小不超过 5MB</div>
          </div>
        </div>
      </el-upload>
    </div>

    <!-- 图片预览区域 -->
    <div v-if="imageList.length > 0" class="image-preview-area">
      <div v-for="(image, index) in imageList" :key="index" class="image-item">
        <el-image
          :src="image"
          :preview-src-list="imageList"
          :initial-index="index"
          fit="cover"
          class="preview-image"
          preview-teleported
        />
        <div class="image-actions">
          <!-- 删除按钮 -->
          <el-button
            type="danger"
            :icon="Delete"
            size="small"
            circle
            @click="handleRemove(index)"
            :disabled="disabled || uploading"
            title="删除"
          />
        </div>
        <div v-if="uploading && index === imageList.length - 1" class="upload-progress">
          <el-progress :percentage="uploadProgress" :show-text="false" />
        </div>
      </div>
      
      <!-- 多图上传时的添加按钮 -->
      <div 
        v-if="multiple && imageList.length < maxCount" 
        class="add-image-btn"
        @click="handleClick"
      >
        <el-icon><Plus /></el-icon>
      </div>
    </div>

    <!-- 上传进度 -->
    <div v-if="uploading" class="upload-status">
      <el-icon class="loading-icon"><Loading /></el-icon>
      <span>上传中...</span>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, computed, watch, nextTick } from 'vue'
import { ElMessage, ElUpload } from 'element-plus'
import { Plus, Delete, Loading } from '@element-plus/icons-vue'
import ossUploader, { type UploadResult } from '@/utils/oss'

interface Props {
  /** 绑定值 */
  modelValue?: string | string[]
  /** 是否支持多图上传 */
  multiple?: boolean
  /** 最大上传数量 */
  maxCount?: number
  /** 是否禁用 */
  disabled?: boolean
  /** 接受的文件类型 */
  accept?: string
  /** 上传文件夹 */
  folder?: string
}

interface Emits {
  (e: 'update:modelValue', value: string | string[]): void
  (e: 'change', value: string | string[]): void
  (e: 'upload-success', result: UploadResult): void
  (e: 'upload-error', error: any): void
}

const props = withDefaults(defineProps<Props>(), {
  multiple: false,
  maxCount: 9,
  disabled: false,
  accept: 'image/*',
  folder: 'images'
})

const emit = defineEmits<Emits>()

const uploadRef = ref<InstanceType<typeof ElUpload>>()
const uploading = ref(false)
const uploadProgress = ref(0)

// 图片列表
const imageList = computed(() => {
  if (!props.modelValue) return []
  return Array.isArray(props.modelValue) ? props.modelValue : [props.modelValue]
})

// 监听外部值变化
watch(
  () => props.modelValue,
  (newVal) => {
    if (!newVal) return
    // 这里可以添加额外的处理逻辑
  },
  { immediate: true }
)

// 点击上传区域
const handleClick = () => {
  if (props.disabled || uploading.value) return
  
  // 检查是否达到最大上传数量
  if (props.multiple && imageList.value.length >= props.maxCount) {
    ElMessage.warning(`最多只能上传 ${props.maxCount} 张图片`)
    return
  }
}

// 上传前验证
const beforeUpload = (file: File) => {
  // 检查文件类型
  const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp']
  if (!allowedTypes.includes(file.type)) {
    ElMessage.error('只支持上传 JPG、PNG、GIF、WebP 格式的图片')
    return false
  }

  // 检查文件大小（5MB）
  const maxSize = 5 * 1024 * 1024
  if (file.size > maxSize) {
    ElMessage.error('图片大小不能超过 5MB')
    return false
  }

  // 检查数量限制
  if (props.multiple && imageList.value.length >= props.maxCount) {
    ElMessage.warning(`最多只能上传 ${props.maxCount} 张图片`)
    return false
  }

  return true
}

// 自定义上传
const handleUpload = async (options: any) => {
  const { file } = options
  
  try {
    uploading.value = true
    uploadProgress.value = 0
    
    // 模拟上传进度
    const progressTimer = setInterval(() => {
      if (uploadProgress.value < 90) {
        uploadProgress.value += 10
      }
    }, 200)
    
    const result = await ossUploader.uploadFile(file, props.folder)
    
    clearInterval(progressTimer)
    uploadProgress.value = 100
    
    // 更新值
    let newValue: string | string[]
    if (props.multiple) {
      newValue = [...imageList.value, result.url]
    } else {
      newValue = result.url
    }
    
    emit('update:modelValue', newValue)
    emit('change', newValue)
    emit('upload-success', result)
    
    ElMessage.success('上传成功')
  } catch (error) {
    console.error('上传失败:', error)
    emit('upload-error', error)
    ElMessage.error('上传失败，请重试')
  } finally {
    uploading.value = false
    uploadProgress.value = 0
  }
}

// 删除图片
const handleRemove = (index: number) => {
  if (props.disabled) return
  
  let newValue: string | string[]
  if (props.multiple) {
    const newList = [...imageList.value]
    newList.splice(index, 1)
    newValue = newList
  } else {
    newValue = ''
  }
  
  emit('update:modelValue', newValue)
  emit('change', newValue)
}
</script>

<style lang="scss" scoped>
.image-upload {
  .upload-area {
    :deep(.el-upload) {
      width: 100%;
    }
    
    :deep(.el-upload-dragger) {
      width: 100%;
      height: 120px;
      border: 2px dashed #d9d9d9;
      border-radius: 6px;
      cursor: pointer;
      position: relative;
      overflow: hidden;
      transition: border-color 0.3s;
      
      &:hover {
        border-color: #409eff;
      }
    }
  }
  
  .upload-content {
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  
  .upload-placeholder {
    text-align: center;
    
    .upload-icon {
      font-size: 28px;
      color: #8c939d;
      margin-bottom: 8px;
    }
    
    .upload-text {
      color: #606266;
      font-size: 14px;
      margin-bottom: 4px;
    }
    
    .upload-tip {
      color: #909399;
      font-size: 12px;
    }
  }
  
  .image-preview-area {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 12px;
    
    .image-item {
      position: relative;
      width: 120px;
      height: 120px;
      border-radius: 8px;
      overflow: hidden;
      border: 1px solid #e4e7ed;
      transition: all 0.3s;
      
      &:hover {
        border-color: #409eff;
        box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2);
      }
      
      .preview-image {
        width: 100%;
        height: 100%;
        cursor: pointer;
      }
      
      .image-actions {
        position: absolute;
        top: 6px;
        right: 6px;
        display: flex;
        gap: 6px;
        opacity: 0;
        transition: opacity 0.3s;
        
        .el-button {
          width: 24px;
          height: 24px;
          padding: 0;
          
          .el-icon {
            font-size: 12px;
          }
        }
      }
      
      .upload-progress {
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        background: rgba(0, 0, 0, 0.7);
        padding: 4px;
      }
      
      &:hover .image-actions {
        opacity: 1;
      }
    }
    
    .add-image-btn {
      width: 120px;
      height: 120px;
      border: 2px dashed #d9d9d9;
      border-radius: 8px;
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
      transition: all 0.3s;
      
      &:hover {
        border-color: #409eff;
        background-color: #f5f7fa;
      }
      
      .el-icon {
        font-size: 24px;
        color: #8c939d;
      }
    }
  }
  
  .upload-status {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 12px;
    color: #409eff;
    font-size: 14px;
    
    .loading-icon {
      animation: rotate 2s linear infinite;
    }
  }
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style>